﻿namespace Pub.Class
{
    using System;
    using System.IO;
    using System.Runtime.CompilerServices;
    using System.Runtime.Serialization.Formatters.Binary;
    using System.Security.Cryptography;
    using System.Text;

    public static class FileStreamExtensions
    {
        public static T FromMemoryStream<T>(this MemoryStream memStream)
        {
            memStream.Position = 0L;
            object obj2 = new BinaryFormatter().Deserialize(memStream);
            memStream.Close();
            return (T) obj2;
        }

        public static Encoding GetEncoding(this FileStream stream)
        {
            return stream.GetEncoding(Encoding.Default);
        }

        public static Encoding GetEncoding(this FileStream stream, Encoding defaultEncoding)
        {
            Encoding bigEndianUnicode = defaultEncoding;
            if (stream.IsNotNull() && (stream.Length >= 2L))
            {
                byte num = 0;
                byte num2 = 0;
                byte num3 = 0;
                long offset = stream.Seek(0L, SeekOrigin.Begin);
                stream.Seek(0L, SeekOrigin.Begin);
                num = Convert.ToByte(stream.ReadByte());
                num2 = Convert.ToByte(stream.ReadByte());
                if (stream.Length >= 3L)
                {
                    num3 = Convert.ToByte(stream.ReadByte());
                }
                if (stream.Length >= 4L)
                {
                    Convert.ToByte(stream.ReadByte());
                }
                if ((num == 0xfe) && (num2 == 0xff))
                {
                    bigEndianUnicode = Encoding.BigEndianUnicode;
                }
                if (((num == 0xff) && (num2 == 0xfe)) && (num3 != 0xff))
                {
                    bigEndianUnicode = Encoding.Unicode;
                }
                if (((num == 0xef) && (num2 == 0xbb)) && (num3 == 0xbf))
                {
                    bigEndianUnicode = Encoding.UTF8;
                }
                stream.Seek(offset, SeekOrigin.Begin);
            }
            return bigEndianUnicode;
        }

        public static string Hash(this Stream strm)
        {
            return strm.MD5();
        }

        public static bool IsUTF8(this FileStream sbInputStream)
        {
            bool flag = true;
            long length = sbInputStream.Length;
            byte num2 = 0;
            for (int i = 0; i < length; i++)
            {
                byte num3 = (byte) sbInputStream.ReadByte();
                if ((num3 & 0x80) != 0)
                {
                    flag = false;
                }
                if (num2 == 0)
                {
                    if (num3 >= 0x80)
                    {
                        do
                        {
                            num3 = (byte) (num3 << 1);
                            num2 = (byte) (num2 + 1);
                        }
                        while ((num3 & 0x80) != 0);
                        num2 = (byte) (num2 - 1);
                        if (num2 == 0)
                        {
                            return false;
                        }
                    }
                }
                else
                {
                    if ((num3 & 0xc0) != 0x80)
                    {
                        return false;
                    }
                    num2 = (byte) (num2 - 1);
                }
            }
            if (num2 > 0)
            {
                return false;
            }
            if (flag)
            {
                return false;
            }
            return true;
        }

        public static string MD5(this Stream strm)
        {
            if ((strm == Stream.Null) || (strm.Length == 0L))
            {
                return null;
            }
            MD5CryptoServiceProvider provider = new MD5CryptoServiceProvider();
            new UTF8Encoding();
            byte[] buffer = provider.ComputeHash(strm);
            StringBuilder builder = new StringBuilder();
            for (int i = 0; i < buffer.Length; i++)
            {
                builder.Append(string.Format("{0:x2}", buffer[i]));
            }
            return builder.ToString();
        }

        public static string ReadAll(this Stream stream)
        {
            return stream.ReadAll(Encoding.UTF8);
        }

        public static string ReadAll(this Stream stream, Encoding encoding)
        {
            stream.Seek(0L, SeekOrigin.Begin);
            using (StreamReader reader = new StreamReader(stream, encoding))
            {
                return reader.ReadToEnd();
            }
        }

        public static string Save(this FileStream file, string path)
        {
            return file.Save(path, false);
        }

        public static string Save(this FileStream file, string path, bool overwrite)
        {
            int num = 1;
            string directoryName = Path.GetDirectoryName(path);
            if (!Directory.Exists(directoryName))
            {
                Directory.CreateDirectory(directoryName);
            }
            int count = Convert.ToInt32(file.Length);
            Path.GetFileName(file.Name);
            byte[] buffer = new byte[count];
            file.Read(buffer, 0, count);
            string str2 = Path.GetDirectoryName(path) + @"\" + Path.GetFileNameWithoutExtension(path);
            while (!overwrite && File.Exists(path))
            {
                string[] strArray = new string[] { str2, "[", num++.ToString(), "]", Path.GetExtension(path) };
                path = string.Concat(strArray);
            }
            File.WriteAllBytes(path, buffer);
            return Path.GetFileName(path);
        }

        public static byte[] ToBytes(this FileStream stream)
        {
            byte[] buffer = new byte[stream.Length];
            stream.Read(buffer, 0, Convert.ToInt32(stream.Length));
            stream.Close();
            return buffer;
        }

        public static byte[] ToBytes(this Stream target)
        {
            if (target.IsNull())
            {
                return new byte[0];
            }
            if (target is MemoryStream)
            {
                return ((MemoryStream) target).ToArray();
            }
            byte[] buffer = new byte[target.Length];
            target.Position = 0L;
            target.Read(buffer, 0, (int) target.Length);
            return buffer;
        }
    }
}

